#!/usr/bin/perl  -w 
use strict;
use warnings;

#std includes
use POSIX qw(strftime);
use File::Basename;

#ml pkg includes
use MLDBUtils::DBConvert;
use MLDBUtils::DBConnect;
use MLDBUtils::DBCustID;

my $MLPROD_HOME = $ENV{'MLPROD_HOME'};
my $PGNAME=basename($0);
my $PGDIRNAME=dirname($0);
my $PGERR=$PGNAME."[$$]";
my $PGUSER=$ENV{'USER'};
my $PGPWD =$ENV{'PWD'};
if($PGDIRNAME !~ m/^\//) {
  $PGDIRNAME="$PGPWD/$PGDIRNAME";
}




# lock cust schema name from folder path
my $g_dbschema    = undef;    # fetch from the locked path
my $g_mod_ctx     = undef;
my $g_cust_id     = undef;    # query the db to get based on schema name
my $g_hospital_id = 1;        # for now hard coded;

if($PGDIRNAME =~ m/^.*\/cust\/(\w+)\/scripts\/(\w+)(\/.*)?$/) {
  $g_dbschema = $1;
  $g_mod_ctx  = $2;
} else {
  print STDERR "$PGNAME: Unable to get cust context from : <$PGDIRNAME>\n";
  exit 1;
}


# globals
my %args;

my $g_dbbasename="$ENV{USER}";
my $g_dbname=$g_dbbasename . "_db";
my $g_dbuser=$g_dbschema . "_" . $g_dbbasename . "_u";
my $g_dbpasswd = undef;
my $g_in_tbl_name  = $g_dbschema . ".read_trans_t";
my $g_out_tbl_name = $g_dbschema . ".temp_batch_trans_t";
my $g_dbconv;
my $g_dbconn;
my $g_dbcust;
my $g_err;
my $g_exitcode = 0;
my $g_acct_hdr_file = undef;
my $g_batch_acct_hdr_file = undef;
my $g_acct_data_file = undef;
my $g_batch_acct_data_file = undef;
my $g_batch_recv_date=undef;
my $g_batch_run_date=undef;
my $g_batch_acct_file = undef;
my $g_seqnum = 1;

#prototypes def here


# all subs here
sub init_args(@)
{
  return 0 unless ((@_ > 1) && (@_ % 2 == 0));
  my %args = ( @_ );


  foreach my $opt (keys(%args)) {
    if     ($opt =~ /-b/)     { $g_batch_recv_date    = $args{$opt}; }
#   if     ($opt =~ /-ihdr/)  { $g_acct_hdr_file      = $args{$opt}; }
#   elsif  ($opt =~ /-ohdr/)  { $g_batch_acct_hdr_file  = $args{$opt}; }
#   elsif  ($opt =~ /-idata/) { $g_acct_data_file     = $args{$opt}; }
#   elsif  ($opt =~ /-odata/) { $g_batch_acct_data_file = $args{$opt}; }
    else  { print STDERR "$PGNAME: invalid option $opt\n"; return 0}
  }

if($g_batch_recv_date =~ /^([0][1-9]|[1][0-2])([0][1-9]|[1-2][0-9]|[3][0-1])([0-9][0-9])_([0-1][0-9]|[2][0-4])([0-5][0-9]|60)([0-5][0-9]|60)_(\d\d\d\d\d\d)/)
{
    $g_batch_run_date = substr($g_batch_recv_date,0,13);
    $g_batch_run_date =~ s/(\d\d)(\d\d)(\d\d)_(\d\d)(\d\d)(\d\d)/$1\/$2\/$3 $4:$5:$6/;
  } else {
    print STDERR "$PGNAME: invalid batch date and time : $g_batch_recv_date\n";
    return 0;
  }
  return 1;

}

sub usage()
{
  print STDERR "Usage: $PGNAME [-h|--help]  ARGS\n";
  print STDERR "  ARGS are\n";
  print STDERR "  [-h|--help]                     => help\n";
  print STDERR "  [-b batch_recv_date AS MMDDYY_HHMMSS_XXXXXX WHERE XXXXXX is cust_id padded with leading 0]  => run date, map to file name\n";
# print STDERR "  [-ihdr in_acct_hdr_file]        => specify or read from stdin\n";
# print STDERR "  [-ohdr out_batch_acct_hdr_file]   => specify or read from stdin\n";
# print STDERR "  [-idata in_acct_data_file]      => specify or read from stdin\n";
# print STDERR "  [-odata out_batch_acct_data_file] => specify or to stdout\n";
}


# do nothing
sub handler_default
{
  my $batch_acct_col_name = shift(@_);
  my $acct_row_hash_ref = shift(@_);
  my $batch_acct_row_hash_ref = shift(@_);

  return 1;
}

# arg1 row data
sub handler_our_run_date
{
  my $batch_acct_col_name = shift(@_);
  my $acct_row_hash_ref = shift(@_);
  my $batch_acct_row_hash_ref = shift(@_);

  #strftime("%D",localtime());
  $batch_acct_row_hash_ref->{$batch_acct_col_name} = $g_batch_run_date;

  return 1;
}

sub handler_cust_id
{
  my $batch_acct_col_name = shift(@_);
  my $acct_row_hash_ref = shift(@_);
  my $batch_acct_row_hash_ref = shift(@_);

  $batch_acct_row_hash_ref->{$batch_acct_col_name} = $g_cust_id;

  return 1;
}

sub handler_seqnum
{
  my $batch_trans_col_name = shift(@_);
  my $trans_row_hash_ref = shift(@_);
  my $batch_trans_row_hash_ref = shift(@_);

  $batch_trans_row_hash_ref->{$batch_trans_col_name} = $g_seqnum;

  $g_seqnum++;

  return 1;
}


sub handler_hid
{
  my $batch_acct_col_name = shift(@_);
  my $acct_row_hash_ref = shift(@_);
  my $batch_acct_row_hash_ref = shift(@_);

  if ($acct_row_hash_ref->{$batch_acct_col_name} eq "") {
  $batch_acct_row_hash_ref->{$batch_acct_col_name} = $g_hospital_id;
  }
  else {
  $batch_acct_row_hash_ref->{$batch_acct_col_name} =  $acct_row_hash_ref->{$batch_acct_col_name};
  }
  $batch_acct_row_hash_ref->{$batch_acct_col_name} = uc($batch_acct_row_hash_ref->{$batch_acct_col_name});
  return 1;
}



sub handler_amount
{
  my $batch_acct_col_name = shift(@_);
  my $acct_row_hash_ref = shift(@_);
  my $batch_acct_row_hash_ref = shift(@_);

  $batch_acct_row_hash_ref->{$batch_acct_col_name} = 
                              $acct_row_hash_ref->{$batch_acct_col_name};

  $batch_acct_row_hash_ref->{$batch_acct_col_name} =~  s/\$\((.*)\)/-$1/;
  $batch_acct_row_hash_ref->{$batch_acct_col_name} =~  s/\$//g;
  $batch_acct_row_hash_ref->{$batch_acct_col_name} =~  s/,//g;
  $batch_acct_row_hash_ref->{$batch_acct_col_name} =~  s/ //g;

  if ( $batch_acct_row_hash_ref->{$batch_acct_col_name} eq "" ) {$batch_acct_row_hash_ref->{$batch_acct_col_name} = 0;}

  return 1;
}


sub loc_format_date_str {
        my $datstr = shift(@_);

        my $y1 = "";
        my $m1 = "";
        my $d1 = "";
        my $retstr = "";
        my $test = "";

        chomp $datstr;
        $datstr =~ s/\.//g;       #remove  '.'
        $datstr =~ s/\s//g;       #remove any space
        $test = $datstr;
        $test =~ s/(\/|0)//g;

        if ( $datstr eq "" || $test eq "") {
                return "";
        }

        my $len = length($datstr);
        if( $len == 6 ) {
                $m1 = substr($datstr,0,2);
                $d1 = substr($datstr,2,2);
                $y1 = substr($datstr,4,2);
                $retstr = "$m1/$d1/$y1";       # insert the slashes
        }
        elsif ( $len == 8  && $datstr !~ /\// && $datstr !~ /-/) {
                $m1 = substr($datstr,0,4);
                $d1 = substr($datstr,4,4);
                if ( $m1 < $d1 ) {  # mmddyyyy
                        $m1 = substr($datstr,0,2);
                        $d1 = substr($datstr,2,2);
                        $y1 = substr($datstr,4,4);
                }
                else {                          # yyyyymmdd
                        $y1 = substr($datstr,0,4);
                        $m1 = substr($datstr,4,2);
                        $d1 = substr($datstr,6,2);
                }
                $retstr = "$m1/$d1/$y1";
        }
        elsif ( $len == 10 ) { # mm-dd-yyyy  or  yyyy/mm/dd
                ($m1, $d1, $y1) = split (/[-\/]/, $datstr);
                if( length($m1) > 2 ) {
                        ($y1, $m1, $d1) = split (/[-\/]/, $datstr);
                }
                $retstr = "$m1/$d1/$y1";
        }
        else {
                $retstr = "";
        }

        return $retstr;
}


sub handler_date
{
  my $batch_acct_col_name = shift(@_);
  my $acct_row_hash_ref = shift(@_);
  my $batch_acct_row_hash_ref = shift(@_);

  my $activity1="";
  my $y1 = "";
  my $m1 = "";
  my $d1 = "";

  $activity1 = $acct_row_hash_ref->{$batch_acct_col_name};
        # $activity1 <-- input date string
  $activity1 = loc_format_date_str( $activity1);

  $batch_acct_row_hash_ref->{$batch_acct_col_name} = $activity1;

  return 1;
}







# all handlers should be defined above this
sub register_batch_acct_handlers()
{
  # STANDARD HANDLERS 
  $g_dbconv->register_handler("our_run_date", \&handler_our_run_date);        # Create our_run_date Field
  $g_dbconv->register_handler("seqnum", \&handler_seqnum);                    # Create seqnum = File Record Number

  # POPULATE NULL VALUES WITH DEFAULTS 
  $g_dbconv->register_handler("hid", \&handler_hid);

  # STANDARD HANDLERS - INSERT null VALUES - DO NOT MODIFY THESE LINES
  $g_dbconv->register_handler("medlytix_denial_code", \&handler_default);
  $g_dbconv->register_handler("first_delivery_date", \&handler_default);
  $g_dbconv->register_handler("trans_type_detail", \&handler_default);
  $g_dbconv->register_handler("medlytix_ins_type", \&handler_default);
  $g_dbconv->register_handler("medlytix_recon_flag", \&handler_default);
  $g_dbconv->register_handler("medlytix_recon_date", \&handler_default);
  

###############################################################
  # BELOW ARE FIELDS SENT BY CLIENT REQUIRING SPECIAL PROCESSING

  # conver currency format i.e $("xxx.xx) to negative
  # strip $ signs
  $g_dbconv->register_handler("trans_amt", \&handler_amount);

  # date treatment;
  $g_dbconv->register_handler("bill_date", \&handler_date);
  $g_dbconv->register_handler("trans_date", \&handler_date);

}


sub DESTROY
{
  print STDERR "EXIT CLEANUP\n";
  if(defined $g_dbconn) {
    $g_dbconn->disconnect;
  }
}


# main process args
if ( @ARGV && (( $ARGV[0] =~ /-h/ ) || (($#ARGV % 2) == 0)) ) {
  usage();
  exit(1);
}

if( ! init_args(@ARGV) ) {
  usage();
  exit 2;
}

$g_dbconn = MLDBUtils::DBConnect->new($g_dbname, $g_dbuser, $g_dbpasswd, \$g_err);
if ( ! defined $g_dbconn ) {
  print STDERR "Unable to connect to DB : $g_err\n";
  exit 3;
}

# get hospital id
$g_dbcust = MLDBUtils::DBCustID->new($g_dbconn, \$g_err);
if ( ! defined $g_dbconn ) {
  print STDERR "Unable to get cust db info : $g_err\n";
  exit 4;
}

if(!$g_dbcust->custid_by_name( $g_dbschema, \$g_cust_id )) {
  print STDERR "Unable to get cust id from db : ", $g_dbcust->errstr, "\n";
  exit 4;
}

if(! defined $g_cust_id || ( $g_cust_id eq "" ) || ($g_cust_id <= 0)) {
  print STDERR "Unable to get hospital system id from db for cust : ", $g_dbschema, "\n";
  exit 4;
}


$g_dbconv = MLDBUtils::DBConvert->new
                 (
                   \$g_err,
                   {
                     dbh           => $g_dbconn,
                     in_tbl_name   => $g_in_tbl_name,
                     out_tbl_name  => $g_out_tbl_name,
                     in_hdr_file   => $g_acct_hdr_file,
                     out_hdr_file  => $g_batch_acct_hdr_file,
                     in_data_file  => $g_acct_data_file,
                     out_data_file => $g_batch_acct_data_file,
                   }
                 );

if( !defined $g_dbconv) {
  print STDERR "Unable to convert : ", $g_err, "\n";
  exit 4;
}

register_batch_acct_handlers();

$g_exitcode = !$g_dbconv->convert();



$g_dbconn->commit;
#$g_dbconn->rollback;
if($g_exitcode) {
  print STDERR "${PGNAME} : conversion failed : $g_dbconv->{errstr}\n";
  $g_batch_acct_file="$ENV{'MLPROD_HOME'}/batch/$g_dbschema/" 
                        . $g_batch_recv_date
                        . "_trans.gpg";
  unlink("$g_batch_acct_file");
}

$g_dbconn->disconnect;
$g_dbconn = undef;

exit($g_exitcode);
